package com.foreverwin.jzymes.framework.quartz.service.impl;

import com.foreverwin.jzymes.common.util.CommonMethods;
import com.foreverwin.jzymes.framework.exception.BusinessException;
import com.foreverwin.jzymes.framework.quartz.constant.ScheduleConstants;
import com.foreverwin.jzymes.framework.quartz.domain.SysJob;
import com.foreverwin.jzymes.framework.quartz.domain.SysJobParam;
import com.foreverwin.jzymes.framework.quartz.service.IScheduleAdviceService;
import com.foreverwin.jzymes.framework.quartz.service.ISysJobParamService;
import com.foreverwin.jzymes.framework.quartz.service.ISysJobScheduleService;
import com.foreverwin.jzymes.framework.quartz.service.ISysJobService;
import com.foreverwin.jzymes.framework.quartz.util.SpringContextUtil;
import com.foreverwin.jzymes.framework.util.I18nUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
public class ScheduleAdviceServiceImpl implements IScheduleAdviceService {

    @Autowired
    ISysJobScheduleService sysJobScheduleService;
    @Autowired
    ISysJobService sysJobService;
    @Autowired
    ISysJobParamService sysJobParamService;

    /**
     * 创建任务
     *
     * @param job
     * @param jobParamList
     */
    @Transactional( propagation = Propagation.REQUIRED, rollbackFor = Exception.class )
    public void createJob( SysJob job, List<SysJobParam> jobParamList ){

        /**检查字段*/
        checkFields( job );

        job.setMisfirePolicy( ScheduleConstants.MISFIRE_DEFAULT );
        job.setCreatedDateTime( new Date() );
        job.setCreateUserBo( CommonMethods.getUserBo() );
        job.setHandle( UUID.randomUUID().toString() );

        saveSysJobParamList( job, jobParamList );

        sysJobScheduleService.insertJobCron( job );
    }

    /**
     * 修改任务
     *
     * @param job
     * @param jobParamList
     */
    @Transactional( propagation = Propagation.REQUIRED, rollbackFor = Exception.class )
    public void updateJob( SysJob job, List<SysJobParam> jobParamList ){

        /**检查字段*/
        checkFields( job );

        job.setMisfirePolicy( ScheduleConstants.MISFIRE_DEFAULT );
        job.setUpdatedDateTime( new Date() );
        job.setUpdateUserBo( CommonMethods.getUserBo() );

        saveSysJobParamList( job, jobParamList );

        sysJobScheduleService.updateJobCron( job );
    }


    public void saveSysJobParamList( SysJob job, List<SysJobParam> jobParamList ){
        SysJobParam querParam = new SysJobParam();
        querParam.setJobBo( job.getHandle() );
        List<SysJobParam> _jobParamList = sysJobParamService.selectSysJobParamList( querParam );
        for( SysJobParam sysJobParam : _jobParamList ){
            sysJobParamService.deleteSysJobParamByIds( sysJobParam.getHandle() );
        }

        for( SysJobParam sysJobParam : jobParamList ){
            /**检查参数名称*/
            Assert.hasText( sysJobParam.getParamName(), I18nUtil.getI18nText("system.quartz.paramNameNotBlank"));

            sysJobParam.setJobBo( job.getHandle() );
            sysJobParam.setHandle( UUID.randomUUID().toString() );
            sysJobParamService.insertSysJobParam( sysJobParam );
        }
    }


    public void checkFields( SysJob job ){
        /**检查站点*/
        Assert.hasText( job.getSite(), I18nUtil.getI18nText( "common.siteNotBlank" ));
        /**检查任务编号*/
        Assert.hasText( job.getJobName(), I18nUtil.getI18nText( "system.quartz.jobNameNotBlank" ));
        Object jobService = SpringContextUtil.getBean( job.getJobName() );
        Assert.notNull( jobService, I18nUtil.getI18nText( "system.quartz.jobNameNotExist", new String[]{ job.getJobName() } ) );
        /**检查任务方法*/
        Assert.hasText( job.getMethodName(), I18nUtil.getI18nText( "system.quartz.methodNameNotBlank" ));
        try {
            Method method = jobService.getClass().getDeclaredMethod( job.getMethodName(), SysJob.class);
        } catch (NoSuchMethodException e) {
            throw BusinessException.build( "system.quartz.methodNameNotExist", new String[]{ job.getJobName(), job.getMethodName() } );
        }
        /**检查执行计划*/
        Assert.hasText( job.getCronExpression(), I18nUtil.getI18nText( "system.quartz.cronExpressionNotBlank" ));
        /**检查任务状态*/
        Assert.hasText( job.getStatus(), I18nUtil.getI18nText( "system.quartz.jobStatusNotBlank" ) );
    }


}
